长时间运行Tomcat进程的类加载器中的java问题
我们在Tomcat 6.0.18上托管了web应用程序,遇到了以下问题:
有两个web应用程序WebApp1和WebApp2,它们都是相同的系统,但版本不同
现在的问题是,当tomcat运行了一周或更长的时间后,有时系统会给出NoClassDefFoundError!此外,我们还遇到了一些奇怪的问题,WebApp1的类加载器加载了WebApp2的jar中的类!WebApp1中也存在相同的jar,但版本不同
当我们重新启动Tomcat时,一切都开始正常工作!我们的JRE是1.5.10
如果您遇到此类问题,请告诉我
问候,, 贾坦·波雷查
# 1 楼答案
我在Tomcat中遇到了许许多多奇怪的类加载器——即使你自己不执行任何类加载器代码,Tomcat本身也很容易产生问题。最常见的问题似乎是反复卸载和重新加载webapp会泄漏类加载器,最终导致Tomcat内存不足
我所看到的版本不匹配的最常见原因是Tomcat确保某些类和JAR(Tomcat本身的一部分)在webapp类路径中领先于任何其他类(commons logging似乎是最常见的例子),并且类加载器可以在你意想不到的时候加载、卸载或保留
你能提供更多的细节吗?如果这个罐子来自第三方,很可能有人以前见过这个问题。如果它是您自己的jar,那么您在应用程序中有自己的类加载器代码吗
# 2 楼答案
我仍然没有足够的代表添加评论,所以我必须发布另一个答案。:)
这听起来像是邮件发送者。类被加载到Tomcat中,而不是每个单独的webapp中。WebApp2首先加载它,然后它就可以工作了,即使它被加载到所有Tomcat中,而不是WebApp2专用的。当WebApp1需要这个类时,它已经看到它的类被加载到Tomcat父类中,并且不会尝试将一个私有类加载到WebApp1
我首先建议你检查一下你的Tomcat,JRE等等。。。查看这些路径中是否有jar或类的副本。之后,我将手动从两个jar文件中删除该类,并重新启动Tomcat或web应用程序,看看会发生什么情况——您可能认为它会失败并生成堆栈跟踪,这将告诉您第一次加载类的位置以及试图加载它的人。(例如,从类名来看,您可能有一个邮件API,加载到Tomcat JVM中,将类加载到Tomcat中,而不是您的webapp中)
# 3 楼答案
您在同一台服务器上托管两个版本的完全相同的代码,有什么特别的原因吗
有两个完全相同名称的不同JAR,包含相同命名空间中的类,并且具有相同的类名,这似乎会导致各种问题(其中最重要的是人为错误)
# 4 楼答案
谢谢克里斯的回复
jar是系统的一部分,它有一些公共类,这些类由其他进程共享
让我们称之为罐子comutils。所以这个场景是这样的
这个MailSender类是singleton
现在有时会发生的事情是,每当WebApp1的代码在使用getInstance方法检索其实例后调用MailSender的任何方法时,实际上调用的是MailSender(版本2),而不是版本1
希望这能给你一些线索